home *** CD-ROM | disk | FTP | other *** search
/ Delphi 2 - Developers' Solutions / Delphi 2 Developers' Solutions.iso / dds / comps / widgets / delphi10 / ulbmpimg / ulbmpimg.pas < prev   
Encoding:
Pascal/Delphi Source File  |  1996-06-16  |  8.5 KB  |  308 lines

  1. unit Ulbmpimg;
  2.  
  3. interface
  4.  
  5. uses
  6.   SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls,
  7.   Forms, Dialogs, ExtCtrls;
  8.  
  9. type
  10.   ULIFile_Bitmap = class( TObject )
  11.   public
  12.     Bitmap_Handle    : HBitmap;   { Holds the DIB when done               }
  13.     Width            : Longint;   { Holds the pixel width when done       }
  14.     Height           : Longint;   { Holds the pixel height when done      }
  15.     The_File         : File;      { File variable for internal use        }
  16.     The_Name         : String;    { Holds the file name                   }
  17.     Bits_Handle      : THandle;   { temporary holder for the DIB          }
  18.     Bits_Byte_Size   : Longint;   { temporary holder for the              }
  19.                                   { byte length of the DIB                }
  20.     Error_Status     : Integer;   { code for error condition on the DIB   }
  21.  
  22.     constructor Create;
  23.     procedure Initialize( The_DIB_Name : String );
  24.     destructor Destroy;
  25.     procedure Get_Bitmap_Data;
  26.     function Get_Bitmap : HBitmap;
  27.     function Load_Bitmap_File : Boolean;
  28.     function Open_DIB : Boolean;
  29.     function Get_Error_Status : Integer;
  30.     procedure Get_DIB_Dimensions( var The_Width  ,
  31.                                       The_Height   : Longint );
  32.   end;
  33.   TUnlimitedBitmapImage = class(TImage)
  34.   private
  35.     { Private declarations }
  36.     FTheFileName : String;
  37.     TheULBMP  : ULIFile_Bitmap;
  38.   protected
  39.     { Protected declarations }
  40.     OldFileName : String;
  41.     TheBitmap : TBitmap;
  42.     valid_load : Boolean;
  43.   public
  44.     { Public declarations }
  45.     constructor Create( AOwner : TComponent ); override;
  46.     destructor Destroy; override;
  47.     procedure Paint; override;
  48.     procedure LoadULBMPFile;
  49.   published
  50.     { Published declarations }
  51.     property TheFileName : String read FTheFileName write FTheFileName;
  52.   end;
  53.  
  54. procedure Register;
  55.  
  56. implementation
  57.  
  58. procedure AHIncr; FAR; EXTERNAL 'KERNEL' INDEX 114;
  59.  
  60. { This creates a file bitmap object }
  61. constructor ULIFile_Bitmap.Create;
  62. begin
  63.   { call inherited FIRST! }
  64.   inherited Create;
  65.   { Zero out the data elements }
  66.   Bitmap_Handle := 0;
  67.   The_Name := '';
  68. end;
  69.  
  70. { This procedure sets up the bitmap filename to load }
  71. procedure ULIFile_Bitmap.Initialize( The_DIB_Name : String );
  72. begin
  73.   The_Name := The_DIB_Name;
  74. end;
  75.  
  76. { This is the destructor procedure }
  77. destructor ULIFile_Bitmap.Destroy;
  78. begin
  79.   { Assume bitmap handle given to TBitmap and cleared there }
  80.   { call inherited last }
  81.   inherited destroy;
  82. end;
  83.  
  84. { This method copies the bitmap bits data from the file into memory. Since }
  85. { copying cannot cross a segment (64K) boundary, segment arithmetic must   }
  86. { be done on the fly.  A LongType type was created to simplify this process}
  87. procedure ULIFile_Bitmap.Get_Bitmap_Data;
  88.  
  89. type
  90.   LongType = record
  91.   case Word of
  92.     0: ( Ptr  : Pointer );
  93.     1: ( Long : Longint );
  94.     2: ( Lo   : Word;
  95.          Hi   : Word    );
  96.   end;
  97. var
  98.   Count   : Longint;
  99.   Start,
  100.   ToAddr,
  101.   Bits    : LongType;
  102. begin
  103.   Start.Long := 0;
  104.   Bits.Ptr := GlobalLock( Bits_Handle );
  105.   Count := Bits_Byte_Size - Start.Long;
  106.   while Count > 0 do
  107.   begin
  108.     ToAddr.Hi := Bits.Hi + ( Start.Hi * OFS( AHIncr ));
  109.     ToAddr.Lo := Start.Lo;
  110.     if Count > $4000 then Count := $4000;
  111.     BlockRead( The_File , ToAddr.Ptr^ , Count );
  112.     Start.Long := Start.Long + Count;
  113.     Count := Bits_Byte_Size - Start.Long;
  114.   end;
  115.   GlobalUnlock( Bits_Handle );
  116. end;
  117.  
  118. { This returns the handle to the stored bitmap }
  119. function ULIFile_Bitmap.Get_Bitmap : HBitmap;
  120. begin
  121.   Get_Bitmap := Bitmap_Handle;
  122. end;
  123.  
  124. { This is the function to call to load a bitmap file of any size }
  125. { If no errors occur it returns true, otherwise false; use GEC   }
  126. { (Some portions of this code are copyright Borland Intl, 1990.) }
  127. function ULIFile_Bitmap.Load_Bitmap_File : Boolean;
  128. var
  129.   Test_Win30_Bitmap : Longint;
  130.   Memory_DC         : HDC;
  131.   The_IO_Result     : Word;
  132. begin
  133.   Error_Status := 0;
  134.   Load_Bitmap_File := false;
  135.   AssignFile( The_File , The_Name );
  136.   {$I-}
  137.   Reset( The_File , 1 );
  138.   Seek( The_File , 14 );
  139.   BlockRead( The_File , Test_Win30_Bitmap , SizeOf( Test_Win30_Bitmap ));
  140.   {$I+}
  141.   The_IO_Result := IOResult;
  142.   If The_IO_Result <> 0 then
  143.   begin
  144.     Error_Status := -1;
  145.   end
  146.   else
  147.   begin
  148.     if Test_Win30_Bitmap = 40 then
  149.     begin
  150.       if Open_DIB then
  151.       begin
  152.         Load_Bitmap_File := true;
  153.       end;
  154.     end
  155.     else
  156.     begin
  157.       Error_Status := -2;
  158.     end;
  159.     CloseFile( The_File );
  160.   end;
  161. end;
  162.  
  163. { This does the actual loading of the bitmap's info }
  164. function ULIFile_Bitmap.Open_DIB : Boolean;
  165. var
  166.   Bit_Count         : Word;
  167.   Size              : Word;
  168.   Long_Width        : Longint;
  169.   DC_Handle         : HDC;
  170.   Bits_Ptr          : Pointer;
  171.   Bitmap_Info       : PBitmapInfo;
  172.   New_Bitmap_Handle : THandle;
  173.   New_Pixel_Width,
  174.   New_Pixel_Height  : Word;
  175. begin
  176.   Open_DIB := true;
  177.   Seek( The_File , 28 );
  178.   BlockRead( The_File , Bit_Count , SizeOf( Bit_Count ));
  179.   if Bit_Count <= 8 then
  180.   begin
  181.     Size := SizeOf( TBitmapInfoHeader ) + (( 1 SHL Bit_Count )
  182.      * SizeOf( TRGBQuad ));
  183.     Bitmap_Info := MemAlloc( Size );
  184.     Seek( The_File , SizeOf( TBitmapFileHeader ));
  185.     BlockRead( The_File , Bitmap_Info^ , Size );
  186.     New_Pixel_Width := Bitmap_Info^.bmiHeader.biWidth;
  187.     New_Pixel_Height := Bitmap_Info^.bmiHeader.biHeight;
  188.     Long_Width := ((( New_Pixel_Width * Bit_Count ) + 31 ) div 32 ) * 4;
  189.     Bitmap_Info^.bmiHeader.biSizeImage := Long_Width * New_Pixel_Height;
  190.     {GlobalCompact( -1 );}
  191.     Bits_Handle := GlobalAlloc( gmem_Moveable or gmem_Zeroinit ,
  192.                                 Bitmap_Info^.bmiHeader.biSizeImage );
  193.     Bits_Byte_Size := Bitmap_Info^.bmiHeader.biSizeImage;
  194.     Get_Bitmap_Data;
  195.     DC_Handle := CreateDC( 'Display' , nil , nil , nil );
  196.     Bits_Ptr := GlobalLock( Bits_Handle );
  197.     New_Bitmap_Handle :=
  198.     CreateDIBitmap( DC_Handle , Bitmap_Info^.bmiHeader ,
  199.                     cbm_Init , Bits_Ptr , Bitmap_Info^ , 0 );
  200.     DeleteDC( DC_Handle );
  201.     GlobalUnlock( Bits_Handle );
  202.     GlobalFree( Bits_Handle );
  203.     FreeMem( Bitmap_Info , Size );
  204.     if New_Bitmap_Handle <> 0 then
  205.     begin
  206.       if Bitmap_Handle <> 0 then DeleteObject( Bitmap_Handle );
  207.       Bitmap_Handle := New_Bitmap_Handle;
  208.       Width := New_Pixel_Width;
  209.       Height := New_Pixel_Height;
  210.     end
  211.     else
  212.     begin
  213.       Open_DIB := false;
  214.       Error_Status := -4;
  215.     end;
  216.   end
  217.   else
  218.   begin
  219.     Open_DIB := false;
  220.     Error_Status := -3;
  221.   end;
  222. end;
  223.  
  224. { This is an OOP return of the error variable }
  225. function ULIFile_Bitmap.Get_Error_Status : Integer;
  226. begin
  227.   Get_Error_Status := Error_Status;
  228. end;
  229.  
  230. { This is an OOP return of the dimensions of the DIB }
  231. procedure ULIFile_Bitmap.Get_DIB_Dimensions( var The_Width  ,
  232.                                               The_Height   : Longint );
  233. begin
  234.   The_Width := Width;
  235.   The_Height := Height;
  236. end;
  237.  
  238. constructor TUnlimitedBitmapImage.Create( AOwner : TComponent );
  239. begin
  240.   inherited Create( AOwner );
  241.   TheBitmap := TBitmap.Create;
  242.   TheULBMP := ULIFile_Bitmap.Create;
  243. end;
  244.  
  245. destructor TUnlimitedBitmapImage.Destroy;
  246. begin
  247.   TheBitmap.Free;
  248.   TheULBMP.Free;
  249.   inherited Destroy;
  250. end;
  251.  
  252. procedure TUnlimitedBitmapImage.LoadULBMPFile;
  253. begin
  254.   Valid_Load := false;
  255.   if not FileExists( TheFileName ) then
  256.   begin
  257.     MessageDlg( TheFileName + ' cannot be found!',mterror,[mbOK],0);
  258.     exit;
  259.   end;
  260.   Screen.Cursor := crHourGlass;
  261.   TheULBMP.Initialize( TheFileName );
  262.   TheULBMP.Load_Bitmap_File;
  263.   TheBitmap.Handle := TheULBMP.Bitmap_Handle;
  264.   TheBitmap.Height := TheULBMP.Height;
  265.   TheBitmap.Width := TheULBMP.Width;
  266.   Screen.Cursor := crDefault;
  267.   oldFileName := TheFileName;
  268.   valid_load := true;
  269. end;
  270.  
  271. procedure TUnlimitedBitmapImage.Paint;
  272. begin
  273.   if csDesigning in ComponentState then
  274.   begin
  275.     inherited Paint;
  276.     exit;
  277.   end;
  278.   if TheFileName = '' then
  279.   begin
  280.     inherited Paint;
  281.     exit;
  282.   end;
  283.   if oldfilename <> Thefilename then
  284.   begin
  285.     LoadULBMPFile;
  286.     if not Valid_load then
  287.     begin
  288.       Picture.Bitmap.Height := 0;
  289.       Picture.Bitmap.Width := 0;
  290.       inherited Paint;
  291.       exit;
  292.     end;
  293.     Picture.Bitmap.Height := TheBitmap.Height;
  294.     Picture.Bitmap.Width := TheBitmap.Width;
  295.     Picture.Bitmap.Handle := TheBitmap.Handle;
  296.     inherited Paint;
  297.     exit;
  298.   end;
  299.   inherited Paint;
  300. end;
  301.  
  302. procedure Register;
  303. begin
  304.   RegisterComponents('Widgets', [TUnlimitedBitmapImage]);
  305. end;
  306.  
  307. end.
  308.